package cn.sourcespro.shiro.filter;

import cn.sourcespro.shiro.crudparams.vo.Vo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * security
 *
 * @author zhanghaowei
 * @date 2018/7/14
 */
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse servletResponse = (HttpServletResponse) response;
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        if (isAjax(servletRequest)) {
            //处理跨域问题，跨域的请求首先会发一个options类型的请求
            if (servletRequest.getMethod().equals(HttpMethod.OPTIONS.name())) {
                return true;
            }
            servletResponse.setCharacterEncoding("UTF-8");
            Subject subject = getSubject(request, response);
            PrintWriter printWriter = servletResponse.getWriter();
            servletResponse.setContentType("application/json;charset=UTF-8");
            servletResponse.setHeader("Access-Control-Allow-Origin", servletRequest.getHeader("Origin"));
            servletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            ObjectMapper mapper = new ObjectMapper();
            String respStr;
            if (subject.getPrincipal() == null) {
                respStr = mapper.writeValueAsString(new Vo("您还未登录，请先登录", HttpStatus.FORBIDDEN));
            } else {
                respStr = mapper.writeValueAsString(new Vo("您没有此权限，请联系管理员", HttpStatus.FORBIDDEN));
            }
            printWriter.write(respStr);
            printWriter.flush();
            servletResponse.setHeader("content-Length", respStr.getBytes().length + "");
            return false;
        } else {
            return super.onAccessDenied(request, response);
        }
    }

    private boolean isAjax(ServletRequest request){
        String header = ((HttpServletRequest) request).getHeader("X-Requested-With");
        if("XMLHttpRequest".equalsIgnoreCase(header)){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

}
